package org.csu.measure.Analyze;

import org.csu.measure.domain.CodeCount;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class LexicalAnalyzer {
    /*
     * 1表示关键字
     * 2表示标识符
     * 3表示常数
     * 4表示运算符
     * 5表示界符
     * 6表示字符串
     * */

    //关键字
    static String []keyWord={"catch","do","for","if","while","switch","case"};
    //运算符
    static String []operation={"+","-","*","/","%","++","--","-=","*=","/=","&","|","^","~","<<",">>",">>>","==","!=",
            ">","<","=",">=","<=","&&","||","!",".","?"};
    //界符
    static String []symbol={",",";",":","(",")","{","}"};

    static ArrayList<String> keyWords=null;
    static ArrayList<String> operations=null;
    static ArrayList<String> symbols=null;

    //指向当前所读到字符串的位置的指针
    static int p,lines;

    //计数
    static int catchCount = 0;
    static int doCount = 0;
    static int forCount = 0;
    static int ifCount = 0;
    static int whileCount = 0;
    static int switchCount = 0;
    static int caseCount = 0;
    static int andCount = 0;
    static int orCount = 0;
    static int circle = 0;
    static int queCount = 0;


    public static int getCircleCount() throws FileNotFoundException {
        init();
        File file=new File("test.java");
        lines=1;
        try(Scanner input=new Scanner(file)) {
            while (input.hasNextLine()){
                String str=input.nextLine();
                if (isReal(str))
                {
                    analyze(str);
                }
                else {
                    continue;
                }
                lines++;
            }
        }
        if(catchCount == 0 && doCount==0 && forCount==0 && ifCount == 0 && whileCount==0 &&switchCount==0 && catchCount==0 && andCount==0 && orCount==0 && queCount==0)
        {
            circle = 0;
        }
        else {
            circle = catchCount+doCount+forCount+ifCount+whileCount+switchCount+caseCount+andCount+orCount+queCount+1;
        }
        print();
        return circle;
    }

    //初始化把数组转换为ArrayList
    public static void init(){
        keyWords=new ArrayList<>();
        operations=new ArrayList<>();
        symbols=new ArrayList<>();
        Collections.addAll(keyWords, keyWord);
        Collections.addAll(operations, operation);
        Collections.addAll(symbols, symbol);

        catchCount = 0;
        doCount = 0;
        forCount = 0;
        ifCount = 0;
        whileCount = 0;
        caseCount = 0;
        andCount = 0;
        orCount = 0;
        queCount = 0;
        circle = 0;
    }

    public static void analyze(String str){
        p=0;
        char ch;
        str=str.trim();
        for (;p<str.length();p++){
            ch=str.charAt(p);
            if (Character.isLetter(ch)||ch=='_'){
                letterCheck(str);
            }else if (ch==' '){
                continue;
            }else {
                symbolCheck(str);
            }
        }
    }

    //标识符，关键字的识别
    public static void letterCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        for (;p<str.length();p++){
            ch=str.charAt(p);
            if (!Character.isLetterOrDigit(ch)&&ch!='_'){
                break;
            }else{
                token+=ch;
            }
        }
        if (keyWords.contains(token)){
            count(token);
        }
        if (p!=str.length()-1||(p==str.length()-1&&(!Character.isLetterOrDigit(str.charAt(p))&&str.charAt(p)!='_'))){
            p--;
        }
    }
    //符号的识别
    public static void symbolCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        if (symbols.contains(token)){
            p--;
        }else {
            if (operations.contains(token)){
                if (p<str.length()){
                    ch=str.charAt(p);
                    if (operations.contains(token+ch)){
                        token+=ch;
                        count(token);
                        p++;
                        if (p<str.length()){
                            ch=str.charAt(p);
                            if (operations.contains(token+ch)){
                                token+=ch;
                            }else{
                                p--;
                            }
                        }
                    }else {
                        p--;
                    }
                }
            }else {
                p--;
            }
        }
    }

    public static void count(String key)
    {
        if(key.equals("catch"))
        {
            catchCount++;
        }
        else if(key.equals("do"))
        {
            doCount++;
        }
        else if(key.equals("for"))
        {
            forCount++;
        }
        else if(key.equals("if"))
        {
            ifCount++;
        }
        else if(key.equals("while"))
        {
            whileCount++;
        }
        else if(key.equals("switch"))
        {
            switchCount++;
        }
        else if(key.equals("case"))
        {
            caseCount++;
        }
        else if(key.equals("&&"))
        {
            andCount++;
        }
        else if(key.equals("||"))
        {
            orCount++;
        }
        else if(key.equals("?"))
        {
            queCount++;
        }
    }

    /**
     * 解析文件
     */
    private static Boolean isReal(String str) {
        // 判断此行是否为注释行
        boolean comment = false;
        String line = "";
        line = str.trim();
        if (line.matches("^[//s&&[^//n]]*$")) {
            // 空行
            comment = true;
        } else if (line.startsWith("/*")) {
            comment = true;
        } else if (comment == true && !line.endsWith("*/")) {
            comment = true;
        } else if (comment == true && line.endsWith("*/")) {
            comment = true;
        } else if (line.startsWith("//")) {
            comment = true;
        } else {
            comment = false;
        }
        return !comment;
    }

    public static void print()
    {
        System.out.println("catchCount: "+catchCount);
        System.out.println("doCount: "+doCount);
        System.out.println("forCount: "+forCount);
        System.out.println("ifCount: "+ifCount);
        System.out.println("whileCount: "+whileCount);
        System.out.println("switchCount: "+switchCount);
        System.out.println("caseCount: "+caseCount);
        System.out.println("andCount: "+andCount);
        System.out.println("orCount: "+orCount);
        System.out.println("queCount: "+queCount);
        System.out.println("circle: "+circle);
    }

}
